<script setup lang="ts" name="DragDropTab">
import { toRefs } from '@vueuse/core'
import { storeToRefs } from 'pinia'
import { useDrag, useDrop } from 'vue3-dnd'
import { getEmptyImage } from 'react-dnd-html5-backend'
import { useLayoutStore } from '@/store/bigScreen/layoutStore'
import CkItem from '../CkItem/index.vue'
import { cloneDeep } from 'lodash-es'
import { getParent, getDropId, getDropLevel, getDropIndex, getNearDropIndex, getNearIndex, isAloneSelf, findFirstVisible, findLastVisible, findVisibleLength } from '../../../utils'

const layoutStore = useLayoutStore()
const { isLayoutDragging, isNear, isNearSelf, isItemSort, dropTo, dropLevel, dropIndex, dropId, layout, currentDragModule } = storeToRefs(layoutStore)

const props = defineProps({
  info: {
    type: Object,
    default: () => {
      return {}
    }
  },
  preview: {
    type: Boolean,
    default: false
  },
  index: {
    type: Number,
    default: 0
  }
})

const cardRef = ref(null)
const position = ref('')
const isFirst = ref(false)
const isEnd = ref(false)

const [dropCollect, drop] = useDrop({
  accept: props.info.config.acceptDragType,
  canDrop: () => {
    return !isItemSort.value
  },
  hover: (item: any, monitor) => {
    if (!cardRef.value) return
    const hoverBoundingRect = cardRef.value?.getBoundingClientRect()
    const clientOffset = monitor.getClientOffset()
    if (item.config.dragType === 'package') {
      if (props.info.config.position === 'left' || props.info.config.position === 'right') {
        // 拖拽对象所在列的索引
        const dragColumnIndex = item.config.position === 'root' ? -1 : layout.value[item.config.position][0].children.findIndex((v) => v.id === item.parent[item.parent.length - 2])
        // 当前放置对象所在列的索引
        const dropColumnIndex = layout.value[props.info.config.position][0].children.findIndex((v) => v.id === props.info.pid)
        // 查找当当前拖拽项所在列数组长度为1时，其临近列的索引，该种情况下，当前拖拽项不可被放置在临近列（也就是不可放在自己本身的位置）
        const nearColumnBeforeIndex = item.config.position === props.info.config.position ? getNearIndex(layout.value[item.config.position][0].children, dragColumnIndex, 'before') : -1
        const nearColumnAfterIndex = item.config.position === props.info.config.position ? getNearIndex(layout.value[item.config.position][0].children, dragColumnIndex, 'after') : -1
        if (clientOffset.x - hoverBoundingRect.left < 10 && props.info.config.position === 'left' && (nearColumnBeforeIndex < 0 || (nearColumnBeforeIndex > 0 && dropColumnIndex !== nearColumnBeforeIndex))) {
          position.value = 'left'
          isNear.value = true
          isNearSelf.value = false
          dropTo.value = 'left'
          dropIndex.value = getNearDropIndex(nearColumnBeforeIndex, dropColumnIndex, 'before')
          dropId.value = layout.value.left[0].id
          dropLevel.value = 'column'
          isFirst.value = dropColumnIndex === findFirstVisible(layout.value[props.info.config.position][0].children)
          isEnd.value = false
        } else if (hoverBoundingRect.right - clientOffset.x < 10 && props.info.config.position === 'left' && dropColumnIndex !== findLastVisible(layout.value[props.info.config.position][0].children) && (nearColumnAfterIndex < 0 || (nearColumnAfterIndex >= 0 && dropColumnIndex !== nearColumnAfterIndex))) {
          position.value = 'right'
          isNear.value = true
          isNearSelf.value = false
          dropTo.value = 'left'
          dropIndex.value = getNearDropIndex(nearColumnAfterIndex, dropColumnIndex, 'after')
          dropId.value = layout.value.left[0].id
          dropLevel.value = 'column'
          isFirst.value = false
          isEnd.value = false
        } else if (clientOffset.x - hoverBoundingRect.left < 10 && props.info.config.position === 'right' && dropColumnIndex !== findFirstVisible(layout.value[props.info.config.position][0].children) && (nearColumnBeforeIndex < 0 || (nearColumnBeforeIndex > 0 && dropColumnIndex !== nearColumnBeforeIndex))) {
          position.value = 'left'
          isNear.value = true
          isNearSelf.value = false
          dropTo.value = 'right'
          dropIndex.value = getNearDropIndex(nearColumnBeforeIndex, dropColumnIndex, 'before')
          dropId.value = layout.value.right[0].id
          dropLevel.value = 'column'
          isFirst.value = false
          isEnd.value = false
        } else if (hoverBoundingRect.right - clientOffset.x < 10 && props.info.config.position === 'right' && (nearColumnAfterIndex < 0 || (nearColumnAfterIndex >= 0 && dropColumnIndex !== nearColumnAfterIndex))) {
          position.value = 'right'
          isNear.value = true
          isNearSelf.value = false
          dropTo.value = 'right'
          dropIndex.value = getNearDropIndex(nearColumnAfterIndex, dropColumnIndex, 'after')
          dropId.value = layout.value.right[0].id
          dropLevel.value = 'column'
          isFirst.value = false
          isEnd.value = dropColumnIndex === findLastVisible(layout.value[props.info.config.position][0].children)
        } else {
          position.value = ''
          isNear.value = false
          isNearSelf.value = false
          dropTo.value = 'root'
          dropIndex.value = -1
          dropId.value = ''
          dropLevel.value = 'aside'
          isFirst.value = false
          isEnd.value = false
        }
      } else if (props.info.config.position === 'root') {
        const dragAsideIndex = item.config.position === 'root' ? layout.value.root.findIndex((v) => v.id === item.parent[item.parent.length - 1]) : -1
        const dropParent = getParent(layout.value.root, props.info.id)
        const dropAsideIndex = layout.value.root.findIndex((v) => v.id === dropParent[dropParent.length - 1])
        // 拖拽对象所在列的索引
        const dragColumnIndex = dragAsideIndex === -1 ? -1 : layout.value.root[dragAsideIndex].children.findIndex((v) => v.id === item.parent[item.parent.length - 2])
        // 当前放置对象所在列的索引
        const dropColumnIndex = layout.value.root[dropAsideIndex].children.findIndex((v) => v.id === dropParent[dropParent.length - 2])
        // 查找当当前拖拽项所在列数组长度为1时，其临近列的索引，该种情况下，当前拖拽项不可被放置在临近列（也就是不可放在自己本身的位置）
        const nearColumnBeforeIndex = item.parent[item.parent.length - 1] === dropParent[dropParent.length - 1] ? getNearIndex(layout.value.root[dropAsideIndex].children, dragColumnIndex, 'before') : -1
        const nearColumnAfterIndex = item.parent[item.parent.length - 1] === dropParent[dropParent.length - 1] ? getNearIndex(layout.value.root[dropAsideIndex].children, dragColumnIndex, 'after') : -1
        if (clientOffset.x - hoverBoundingRect.left < 10 && (nearColumnBeforeIndex < 0 || (nearColumnBeforeIndex > 0 && dropColumnIndex !== nearColumnBeforeIndex))) {
          position.value = 'left'
          isNear.value = true
          isNearSelf.value = false
          dropTo.value = 'root'
          dropIndex.value = getNearDropIndex(nearColumnBeforeIndex, dropColumnIndex, 'before')
          dropId.value = layout.value.root[dropAsideIndex].id
          dropLevel.value = 'column'
          isFirst.value = dropColumnIndex === findFirstVisible(layout.value[props.info.config.position][dropAsideIndex].children)
          isEnd.value = false
        } else if (hoverBoundingRect.right - clientOffset.x < 10 && (nearColumnAfterIndex < 0 || (nearColumnAfterIndex >= 0 && dropColumnIndex !== nearColumnAfterIndex))) {
          position.value = 'right'
          isNear.value = true
          isNearSelf.value = false
          dropTo.value = 'root'
          dropIndex.value = getNearDropIndex(nearColumnAfterIndex, dropColumnIndex, 'after')
          dropId.value = layout.value.root[dropAsideIndex].id
          dropLevel.value = 'column'
          isFirst.value = false
          isEnd.value = dropColumnIndex === findLastVisible(layout.value[props.info.config.position][dropAsideIndex].children)
        } else {
          position.value = ''
          isNear.value = false
          isNearSelf.value = false
          dropTo.value = 'root'
          dropIndex.value = -1
          dropId.value = ''
          dropLevel.value = 'aside'
          isFirst.value = false
          isEnd.value = false
        }
      } else {
        position.value = ''
        isNear.value = false
        isNearSelf.value = false
        dropTo.value = 'root'
        dropIndex.value = -1
        dropId.value = ''
        dropLevel.value = 'aside'
        isFirst.value = false
        isEnd.value = false
      }
    } else if (item.config.dragType === 'tab') {
      if (props.info.config.position === 'left' || props.info.config.position === 'right') {
        // 拖拽对象所在列的索引
        const dragColumnIndex = item.config.position === 'root' ? -1 : layout.value[item.config.position][0].children.findIndex((v) => v.id === item.parent[item.parent.length - 2])
        // 当前放置对象所在列的索引
        const dropColumnIndex = layout.value[props.info.config.position][0].children.findIndex((v) => v.id === props.info.pid)
        // 查找当当前拖拽项所在列数组长度为1时，其临近列的索引，该种情况下，当前拖拽项不可被放置在临近列（也就是不可放在自己本身的位置）
        const nearColumnBeforeIndex = item.config.position === props.info.config.position && findVisibleLength(layout.value[item.config.position][0].children[dragColumnIndex].children) === 1 ? getNearIndex(layout.value[item.config.position][0].children, dragColumnIndex, 'before') : -1
        const nearColumnAfterIndex = item.config.position === props.info.config.position && findVisibleLength(layout.value[item.config.position][0].children[dragColumnIndex].children) === 1 ? getNearIndex(layout.value[item.config.position][0].children, dragColumnIndex, 'after') : -1
        const nearTabBeforeIndex = item.pid === props.info.pid && findVisibleLength(layout.value[item.config.position][0].children[dragColumnIndex].children) > 1 ? getNearIndex(layout.value[item.config.position][0].children[dragColumnIndex].children, item.index, 'before') : -1
        const nearTabAfterIndex = item.pid === props.info.pid && findVisibleLength(layout.value[item.config.position][0].children[dragColumnIndex].children) > 1 ? getNearIndex(layout.value[item.config.position][0].children[dragColumnIndex].children, item.index, 'after') : -1
        const isAloneTabSelf = isAloneSelf(layout.value[props.info.config.position][0].children[dropColumnIndex], item)
        if (clientOffset.x - hoverBoundingRect.left < 10 && props.info.config.position === 'left' && !isAloneTabSelf && (nearColumnBeforeIndex < 0 || (nearColumnBeforeIndex > 0 && dropColumnIndex !== nearColumnBeforeIndex))) {
          position.value = 'left'
          isNear.value = true
          isNearSelf.value = false
          dropTo.value = 'left'
          dropIndex.value = getNearDropIndex(nearColumnBeforeIndex, dropColumnIndex, 'before')
          dropId.value = layout.value.left[0].id
          dropLevel.value = 'column'
          isFirst.value = dropColumnIndex === findFirstVisible(layout.value[props.info.config.position][0].children)
          isEnd.value = false
        } else if (hoverBoundingRect.right - clientOffset.x < 10 && props.info.config.position === 'left' && !isAloneTabSelf && dropColumnIndex !== findLastVisible(layout.value[props.info.config.position][0].children) && (nearColumnAfterIndex < 0 || (nearColumnAfterIndex >= 0 && dropColumnIndex !== nearColumnAfterIndex))) {
          position.value = 'right'
          isNear.value = true
          isNearSelf.value = false
          dropTo.value = 'left'
          dropIndex.value = getNearDropIndex(nearColumnAfterIndex, dropColumnIndex, 'after')
          dropId.value = layout.value.left[0].id
          dropLevel.value = 'column'
          isFirst.value = false
          isEnd.value = false
        } else if (clientOffset.x - hoverBoundingRect.left < 10 && props.info.config.position === 'right' && !isAloneTabSelf && dropColumnIndex !== findFirstVisible(layout.value[props.info.config.position][0].children) && (nearColumnBeforeIndex < 0 || (nearColumnBeforeIndex > 0 && dropColumnIndex !== nearColumnBeforeIndex))) {
          position.value = 'left'
          isNear.value = true
          isNearSelf.value = false
          dropTo.value = 'right'
          dropIndex.value = getNearDropIndex(nearColumnBeforeIndex, dropColumnIndex, 'before')
          dropId.value = layout.value.right[0].id
          dropLevel.value = 'column'
          isFirst.value = false
          isEnd.value = false
        } else if (hoverBoundingRect.right - clientOffset.x < 10 && props.info.config.position === 'right' && !isAloneTabSelf && (nearColumnAfterIndex < 0 || (nearColumnAfterIndex >= 0 && dropColumnIndex !== nearColumnAfterIndex))) {
          position.value = 'right'
          isNear.value = true
          isNearSelf.value = false
          dropTo.value = 'right'
          dropIndex.value = getNearDropIndex(nearColumnAfterIndex, dropColumnIndex, 'after')
          dropId.value = layout.value.right[0].id
          dropLevel.value = 'column'
          isFirst.value = false
          isEnd.value = dropColumnIndex === findLastVisible(layout.value[props.info.config.position][0].children)
        } else if (clientOffset.y - hoverBoundingRect.top < 24 && clientOffset.y - hoverBoundingRect.top > 5 && item.id === props.info.id) {
          position.value = 'self'
          isNear.value = true
          isNearSelf.value = true
          dropTo.value = props.info.config.position
          dropIndex.value = getDropIndex(layout.value, 0, dropColumnIndex, props.info, props.index, item.config.dragType)
          dropId.value = getDropId(layout.value, 0, dropColumnIndex, props.info, props.index, item.config.dragType)
          dropLevel.value = getDropLevel(layout.value, 0, dropColumnIndex, props.info, props.index, item.config.dragType)
          isFirst.value = false
          isEnd.value = false
        } else if (clientOffset.y - hoverBoundingRect.top < 24 && clientOffset.y - hoverBoundingRect.top > 5 && item.id !== props.info.id) {
          position.value = 'self'
          isNear.value = true
          isNearSelf.value = false
          dropTo.value = props.info.config.position
          dropIndex.value = -1
          dropId.value = props.info.id
          dropLevel.value = 'item'
          isFirst.value = false
          isEnd.value = false
        } else if (clientOffset.y - hoverBoundingRect.top <= 5 && item.id !== props.info.id && (nearTabBeforeIndex < 0 || (nearTabBeforeIndex > 0 && props.index !== nearTabBeforeIndex))) {
          position.value = 'top'
          isNear.value = true
          isNearSelf.value = false
          dropTo.value = props.info.config.position
          dropIndex.value = getNearDropIndex(nearTabBeforeIndex, props.index, 'before')
          dropId.value = props.info.pid
          dropLevel.value = 'tab'
          isFirst.value = props.index === findFirstVisible(layout.value[props.info.config.position][0].children[dropColumnIndex].children)
          isEnd.value = false
        } else if (hoverBoundingRect.bottom - clientOffset.y <= 5 && item.id !== props.info.id && (nearTabAfterIndex < 0 || (nearTabAfterIndex >= 0 && props.index !== nearTabAfterIndex))) {
          position.value = 'bottom'
          isNear.value = true
          isNearSelf.value = false
          dropTo.value = props.info.config.position
          dropIndex.value = getNearDropIndex(nearTabAfterIndex, props.index, 'after')
          dropId.value = props.info.pid
          dropLevel.value = 'tab'
          isFirst.value = false
          isEnd.value = props.index === findLastVisible(layout.value[props.info.config.position][0].children[dropColumnIndex].children)
        } else {
          position.value = ''
          isNear.value = false
          isNearSelf.value = false
          dropTo.value = 'root'
          dropIndex.value = -1
          dropId.value = ''
          dropLevel.value = 'aside'
          isFirst.value = false
          isEnd.value = false
        }
      } else if (props.info.config.position === 'bottom') {
        const nearTabBeforeIndex = item.pid === props.info.pid && findVisibleLength(layout.value.bottom) > 1 ? getNearIndex(layout.value.bottom, item.index, 'before') : -1
        const nearTabAfterIndex = item.pid === props.info.pid && findVisibleLength(layout.value.bottom) > 1 ? getNearIndex(layout.value.bottom, item.index, 'after') : -1
        if (clientOffset.y - hoverBoundingRect.top < 24 && clientOffset.y - hoverBoundingRect.top > 5 && item.id === props.info.id) {
          position.value = 'self'
          isNear.value = true
          isNearSelf.value = true
          dropTo.value = props.info.config.position
          dropIndex.value = props.index
          dropId.value = ''
          dropLevel.value = 'tab'
          isFirst.value = false
          isEnd.value = false
        } else if (clientOffset.y - hoverBoundingRect.top < 24 && clientOffset.y - hoverBoundingRect.top > 5 && item.id !== props.info.id) {
          position.value = 'self'
          isNear.value = true
          isNearSelf.value = false
          dropTo.value = props.info.config.position
          dropIndex.value = -1
          dropId.value = props.info.id
          dropLevel.value = 'item'
          isFirst.value = false
          isEnd.value = false
        } else if (clientOffset.y - hoverBoundingRect.top <= 5 && item.id !== props.info.id && props.index !== findFirstVisible(layout.value[props.info.config.position]) && (nearTabBeforeIndex < 0 || (nearTabBeforeIndex > 0 && props.index !== nearTabBeforeIndex))) {
          position.value = 'top'
          isNear.value = true
          isNearSelf.value = false
          dropTo.value = props.info.config.position
          dropIndex.value = getNearDropIndex(nearTabBeforeIndex, props.index, 'before')
          dropId.value = ''
          dropLevel.value = 'tab'
          isFirst.value = false
          isEnd.value = false
        } else if (hoverBoundingRect.bottom - clientOffset.y <= 5 && item.id !== props.info.id && (nearTabAfterIndex < 0 || (nearTabAfterIndex > 0 && props.index !== nearTabAfterIndex))) {
          position.value = 'bottom'
          isNear.value = true
          isNearSelf.value = false
          dropTo.value = props.info.config.position
          dropIndex.value = getNearDropIndex(nearTabAfterIndex, props.index, 'after')
          dropId.value = ''
          dropLevel.value = 'tab'
          isFirst.value = false
          isEnd.value = props.index === findLastVisible(layout.value[props.info.config.position])
        } else {
          position.value = ''
          isNear.value = false
          isNearSelf.value = false
          dropTo.value = 'root'
          dropIndex.value = -1
          dropId.value = ''
          dropLevel.value = 'aside'
          isFirst.value = false
          isEnd.value = false
        }
      } else {
        // 放置的是root中的tab
        const dragAsideIndex = item.config.position === 'root' ? layout.value.root.findIndex((v) => v.id === item.parent[item.parent.length - 1]) : -1
        const dropParent = getParent(layout.value.root, props.info.id)
        const dropAsideIndex = layout.value.root.findIndex((v) => v.id === dropParent[dropParent.length - 1])
        // 拖拽对象所在列的索引
        const dragColumnIndex = dragAsideIndex === -1 ? -1 : layout.value.root[dragAsideIndex].children.findIndex((v) => v.id === item.parent[item.parent.length - 2])
        // 当前放置对象所在列的索引
        const dropColumnIndex = layout.value.root[dropAsideIndex].children.findIndex((v) => v.id === dropParent[dropParent.length - 2])
        // 查找当当前拖拽项所在列数组长度为1时，其临近列的索引，该种情况下，当前拖拽项不可被放置在临近列（也就是不可放在自己本身的位置）
        const nearColumnBeforeIndex = item.parent[item.parent.length - 1] === dropParent[dropParent.length - 1] && findVisibleLength(layout.value[item.config.position][dragAsideIndex].children[dragColumnIndex].children) === 1 ? getNearIndex(layout.value[item.config.position][dragAsideIndex].children, dragColumnIndex, 'before') : -1
        const nearColumnAfterIndex = item.parent[item.parent.length - 1] === dropParent[dropParent.length - 1] && findVisibleLength(layout.value[item.config.position][dragAsideIndex].children[dragColumnIndex].children) === 1 ? getNearIndex(layout.value[item.config.position][dragAsideIndex].children, dragColumnIndex, 'after') : -1
        const nearTabBeforeIndex = item.parent[item.parent.length - 2] === dropParent[dropParent.length - 2] && findVisibleLength(layout.value[item.config.position][dragAsideIndex].children[dragColumnIndex].children) > 1 ? getNearIndex(layout.value[item.config.position][dragAsideIndex].children[dragColumnIndex].children, item.index, 'before') : -1
        const nearTabAfterIndex = item.parent[item.parent.length - 2] === dropParent[dropParent.length - 2] && findVisibleLength(layout.value[item.config.position][dragAsideIndex].children[dragColumnIndex].children) > 1 ? getNearIndex(layout.value[item.config.position][dragAsideIndex].children[dragColumnIndex].children, item.index, 'after') : -1
        const isAloneTabSelf = isAloneSelf(layout.value.root[dropAsideIndex].children[dropColumnIndex], item)
        if (clientOffset.x - hoverBoundingRect.left < 10 && !isAloneTabSelf && (nearColumnBeforeIndex < 0 || (nearColumnBeforeIndex > 0 && dropColumnIndex !== nearColumnBeforeIndex))) {
          position.value = 'left'
          isNear.value = true
          isNearSelf.value = false
          dropTo.value = 'root'
          dropIndex.value = getNearDropIndex(nearColumnBeforeIndex, dropColumnIndex, 'before')
          dropId.value = layout.value.root[dropAsideIndex].id
          dropLevel.value = 'column'
          isFirst.value = dropColumnIndex === findFirstVisible(layout.value[props.info.config.position][dropAsideIndex].children)
          isEnd.value = false
        } else if (hoverBoundingRect.right - clientOffset.x < 10 && !isAloneTabSelf && (nearColumnAfterIndex < 0 || (nearColumnAfterIndex >= 0 && dropColumnIndex !== nearColumnAfterIndex))) {
          position.value = 'right'
          isNear.value = true
          isNearSelf.value = false
          dropTo.value = 'root'
          dropIndex.value = getNearDropIndex(nearColumnAfterIndex, dropColumnIndex, 'after')
          dropId.value = layout.value.root[dropAsideIndex].id
          dropLevel.value = 'column'
          isFirst.value = false
          isEnd.value = dropColumnIndex === findLastVisible(layout.value[props.info.config.position][dropAsideIndex].children)
        } else if (clientOffset.y - hoverBoundingRect.top < 24 && clientOffset.y - hoverBoundingRect.top > 5 && item.id === props.info.id && !(findVisibleLength(layout.value.root[dragAsideIndex].children) === 1 && findVisibleLength(layout.value[props.info.config.position][dragAsideIndex].children[findFirstVisible(layout.value[props.info.config.position][dropAsideIndex].children)].children) === 1)) {
          position.value = 'self'
          isNear.value = true
          isNearSelf.value = true
          dropTo.value = props.info.config.position
          dropIndex.value = getDropIndex(layout.value, dropAsideIndex, dropColumnIndex, props.info, props.index, item.config.dragType)
          dropId.value = getDropId(layout.value, dropAsideIndex, dropColumnIndex, props.info, props.index, item.config.dragType)
          dropLevel.value = getDropLevel(layout.value, dropAsideIndex, dropColumnIndex, props.info, props.index, item.config.dragType)
          isFirst.value = false
          isEnd.value = false
        } else if (clientOffset.y - hoverBoundingRect.top < 24 && clientOffset.y - hoverBoundingRect.top > 5 && item.id !== props.info.id) {
          position.value = 'self'
          isNear.value = true
          isNearSelf.value = false
          dropTo.value = props.info.config.position
          dropIndex.value = -1
          dropId.value = props.info.id
          dropLevel.value = 'item'
          isFirst.value = false
          isEnd.value = false
        } else if (clientOffset.y - hoverBoundingRect.top <= 5 && item.id !== props.info.id && (nearTabBeforeIndex < 0 || (nearTabBeforeIndex > 0 && props.index !== nearTabBeforeIndex))) {
          position.value = 'top'
          isNear.value = true
          isNearSelf.value = false
          dropTo.value = props.info.config.position
          dropIndex.value = getNearDropIndex(nearTabBeforeIndex, props.index, 'before')
          dropId.value = props.info.pid
          dropLevel.value = 'tab'
          isFirst.value = props.index === findFirstVisible(layout.value[props.info.config.position][dropAsideIndex].children[dropColumnIndex].children)
          isEnd.value = false
        } else if (hoverBoundingRect.bottom - clientOffset.y <= 5 && item.id !== props.info.id && (nearTabAfterIndex < 0 || (nearTabAfterIndex >= 0 && props.index !== nearTabAfterIndex))) {
          position.value = 'bottom'
          isNear.value = true
          isNearSelf.value = false
          dropTo.value = props.info.config.position
          dropIndex.value = getNearDropIndex(nearTabAfterIndex, props.index, 'after')
          dropId.value = props.info.pid
          dropLevel.value = 'tab'
          isFirst.value = false
          isEnd.value = props.index === findLastVisible(layout.value[props.info.config.position][dropAsideIndex].children[dropColumnIndex].children)
        } else {
          position.value = ''
          isNear.value = false
          isNearSelf.value = false
          dropTo.value = 'root'
          dropIndex.value = -1
          dropId.value = ''
          dropLevel.value = 'aside'
          isFirst.value = false
          isEnd.value = false
        }
      }
    } else if (item.config.dragType === 'item') {
      if (isItemSort.value) {
        if (clientOffset.y - hoverBoundingRect.top >= 24 || clientOffset.y - hoverBoundingRect.top <= 5) {
          isItemSort.value = false
          layoutStore.setCurrentDraggingPreviewModule(item)
        }
      } else {
        if (props.info.config.position === 'left' || props.info.config.position === 'right') {
          // 拖拽对象所在列的索引
          const dragColumnIndex = item.config.position === 'root' || item.config.position === 'bottom' ? -1 : layout.value[item.config.position][0].children.findIndex((v) => v.id === item.parent[item.parent.length - 2])
          // 当前放置对象所在列的索引
          const dropColumnIndex = layout.value[props.info.config.position][0].children.findIndex((v) => v.id === props.info.pid)
          const dragTabIndex = item.config.position === 'root' || item.config.position === 'bottom' || dragColumnIndex < 0 ? -1 : layout.value[item.config.position][0].children[dragColumnIndex].children.findIndex((v) => v.id === item.parent[item.parent.length - 3])
          // 查找当当前拖拽项所在列数组长度为1时，其临近列的索引，该种情况下，当前拖拽项不可被放置在临近列（也就是不可放在自己本身的位置）
          const nearColumnBeforeIndex = item.config.position === props.info.config.position && findVisibleLength(layout.value[item.config.position][0].children[dragColumnIndex].children) === 1 && findVisibleLength(layout.value[item.config.position][0].children[dragColumnIndex].children[dragTabIndex].children) === 1 ? getNearIndex(layout.value[item.config.position][0].children, dragColumnIndex, 'before') : -1
          const nearColumnAfterIndex = item.config.position === props.info.config.position && findVisibleLength(layout.value[item.config.position][0].children[dragColumnIndex].children) === 1 && findVisibleLength(layout.value[item.config.position][0].children[dragColumnIndex].children[dragTabIndex].children) === 1 ? getNearIndex(layout.value[item.config.position][0].children, dragColumnIndex, 'after') : -1
          const nearTabBeforeIndex = item.parent[item.parent.length - 2] === props.info.pid && findVisibleLength(layout.value[item.config.position][0].children[dragColumnIndex].children) > 1 && findVisibleLength(layout.value[item.config.position][0].children[dragColumnIndex].children[dragTabIndex].children) === 1 ? getNearIndex(layout.value[item.config.position][0].children[dragColumnIndex].children, dragTabIndex, 'before') : -1
          const nearTabAfterIndex = item.parent[item.parent.length - 2] === props.info.pid && findVisibleLength(layout.value[item.config.position][0].children[dragColumnIndex].children) > 1 && findVisibleLength(layout.value[item.config.position][0].children[dragColumnIndex].children[dragTabIndex].children) === 1 ? getNearIndex(layout.value[item.config.position][0].children[dragColumnIndex].children, dragTabIndex, 'after') : -1
          const isAloneItemSelf = isAloneSelf(layout.value[props.info.config.position][0].children[dropColumnIndex], item)
          if (clientOffset.x - hoverBoundingRect.left < 10 && props.info.config.position === 'left' && !isAloneItemSelf && (nearColumnBeforeIndex < 0 || (nearColumnBeforeIndex > 0 && dropColumnIndex !== nearColumnBeforeIndex))) {
            position.value = 'left'
            isNear.value = true
            isNearSelf.value = false
            dropTo.value = 'left'
            dropIndex.value = getNearDropIndex(nearColumnBeforeIndex, dropColumnIndex, 'before')
            dropId.value = layout.value.left[0].id
            dropLevel.value = 'column'
            isFirst.value = dropColumnIndex === findFirstVisible(layout.value[props.info.config.position][0].children)
            isEnd.value = false
          } else if (hoverBoundingRect.right - clientOffset.x < 10 && props.info.config.position === 'left' && !isAloneItemSelf && dropColumnIndex !== findLastVisible(layout.value[props.info.config.position][0].children) && (nearColumnAfterIndex < 0 || (nearColumnAfterIndex >= 0 && dropColumnIndex !== nearColumnAfterIndex))) {
            position.value = 'right'
            isNear.value = true
            isNearSelf.value = false
            dropTo.value = 'left'
            dropIndex.value = getNearDropIndex(nearColumnAfterIndex, dropColumnIndex, 'after')
            dropId.value = layout.value.left[0].id
            dropLevel.value = 'column'
            isFirst.value = false
            isEnd.value = false
          } else if (clientOffset.x - hoverBoundingRect.left < 10 && props.info.config.position === 'right' && !isAloneItemSelf && dropColumnIndex !== findFirstVisible(layout.value[props.info.config.position][0].children) && (nearColumnBeforeIndex < 0 || (nearColumnBeforeIndex > 0 && dropColumnIndex !== nearColumnBeforeIndex))) {
            position.value = 'left'
            isNear.value = true
            isNearSelf.value = false
            dropTo.value = 'right'
            dropIndex.value = getNearDropIndex(nearColumnBeforeIndex, dropColumnIndex, 'before')
            dropId.value = layout.value.right[0].id
            dropLevel.value = 'column'
            isFirst.value = false
            isEnd.value = false
          } else if (hoverBoundingRect.right - clientOffset.x < 10 && props.info.config.position === 'right' && !isAloneItemSelf && (nearColumnAfterIndex < 0 || (nearColumnAfterIndex >= 0 && dropColumnIndex !== nearColumnAfterIndex))) {
            position.value = 'right'
            isNear.value = true
            isNearSelf.value = false
            dropTo.value = 'right'
            dropIndex.value = getNearDropIndex(nearColumnAfterIndex, dropColumnIndex, 'after')
            dropId.value = layout.value.right[0].id
            dropLevel.value = 'column'
            isFirst.value = false
            isEnd.value = dropColumnIndex === findLastVisible(layout.value[props.info.config.position][0].children)
          } else if (clientOffset.y - hoverBoundingRect.top < 24 && clientOffset.y - hoverBoundingRect.top > 5 && isAloneItemSelf && item.pid === props.info.id) {
            position.value = 'self'
            isNear.value = true
            isNearSelf.value = true
            dropTo.value = props.info.config.position
            dropIndex.value = getDropIndex(layout.value, 0, dropColumnIndex, props.info, props.index, item.config.dragType)
            dropId.value = getDropId(layout.value, 0, dropColumnIndex, props.info, props.index, item.config.dragType)
            dropLevel.value = getDropLevel(layout.value, 0, dropColumnIndex, props.info, props.index, item.config.dragType)
            isFirst.value = false
            isEnd.value = false
          } else if (clientOffset.y - hoverBoundingRect.top < 24 && clientOffset.y - hoverBoundingRect.top > 5 && !isAloneItemSelf && findVisibleLength(layout.value[props.info.config.position][0].children[dropColumnIndex].children[props.index].children) > 1 && item.pid === props.info.id) {
            position.value = 'self'
            isNear.value = true
            isNearSelf.value = true
            dropTo.value = props.info.config.position
            dropIndex.value = -1
            dropId.value = props.info.id
            dropLevel.value = 'item'
            isFirst.value = false
            isEnd.value = false
          } else if (clientOffset.y - hoverBoundingRect.top < 24 && clientOffset.y - hoverBoundingRect.top > 5 && !isAloneItemSelf && findVisibleLength(layout.value[props.info.config.position][0].children[dropColumnIndex].children[props.index].children) === 1 && item.pid === props.info.id) {
            position.value = 'self'
            isNear.value = true
            isNearSelf.value = true
            dropTo.value = props.info.config.position
            dropIndex.value = props.index
            dropId.value = props.info.pid
            dropLevel.value = 'tab'
            isFirst.value = false
            isEnd.value = false
          } else if (clientOffset.y - hoverBoundingRect.top < 24 && clientOffset.y - hoverBoundingRect.top > 5 && item.pid !== props.info.id) {
            position.value = 'self'
            isNear.value = true
            isNearSelf.value = false
            dropTo.value = props.info.config.position
            dropIndex.value = -1
            dropId.value = props.info.id
            dropLevel.value = 'item'
            isFirst.value = false
            isEnd.value = false
          } else if (clientOffset.y - hoverBoundingRect.top <= 5 && (item.pid !== props.info.id || item.pid === props.info.id && findVisibleLength(layout.value[props.info.config.position][0].children[dropColumnIndex].children[dragTabIndex].children) > 1) && (nearTabBeforeIndex < 0 || (nearTabBeforeIndex > 0 && props.index !== nearTabBeforeIndex))) {
            position.value = 'top'
            isNear.value = true
            isNearSelf.value = false
            dropTo.value = props.info.config.position
            dropIndex.value = getNearDropIndex(nearTabBeforeIndex, props.index, 'before')
            dropId.value = props.info.pid
            dropLevel.value = 'tab'
            isFirst.value = props.index === findFirstVisible(layout.value[props.info.config.position][0].children[dropColumnIndex].children)
            isEnd.value = false
          } else if (hoverBoundingRect.bottom - clientOffset.y <= 5 && (item.pid !== props.info.id || item.pid === props.info.id && findVisibleLength(layout.value[props.info.config.position][0].children[dropColumnIndex].children[dragTabIndex].children) > 1) && (nearTabAfterIndex < 0 || (nearTabAfterIndex >= 0 && props.index !== nearTabAfterIndex))) {
            position.value = 'bottom'
            isNear.value = true
            isNearSelf.value = false
            dropTo.value = props.info.config.position
            dropIndex.value = getNearDropIndex(nearTabAfterIndex, props.index, 'after')
            dropId.value = props.info.pid
            dropLevel.value = 'tab'
            isFirst.value = false
            isEnd.value = props.index === findLastVisible(layout.value[props.info.config.position][0].children[dropColumnIndex].children)
          } else {
            position.value = ''
            isNear.value = false
            isNearSelf.value = false
            dropTo.value = 'root'
            dropIndex.value = -1
            dropId.value = ''
            dropLevel.value = 'aside'
            isFirst.value = false
            isEnd.value = false
          }
        } else if (props.info.config.position === 'bottom') {
          const dragTabIndex = item.config.position !== 'bottom' ? -1 : layout.value.bottom.findIndex((v) => v.id === item.parent[item.parent.length - 1])
          const nearTabBeforeIndex = item.config.position === props.info.config.position && findVisibleLength(layout.value.bottom) > 1 && findVisibleLength(layout.value.bottom[dragTabIndex].children) === 1 ? getNearIndex(layout.value.bottom, dragTabIndex, 'before') : -1
          const nearTabAfterIndex = item.config.position === props.info.config.position && findVisibleLength(layout.value.bottom) > 1 && findVisibleLength(layout.value.bottom[dragTabIndex].children) === 1 ? getNearIndex(layout.value.bottom, dragTabIndex, 'after') : -1
          if (clientOffset.y - hoverBoundingRect.top < 24 && clientOffset.y - hoverBoundingRect.top > 5 && findVisibleLength(layout.value.bottom[props.index].children) === 1 && item.pid === props.info.id) {
            position.value = 'self'
            isNear.value = true
            isNearSelf.value = true
            dropTo.value = props.info.config.position
            dropIndex.value = layout.value.bottom.length === 1 ? -1 : props.index
            dropId.value = ''
            dropLevel.value = 'tab'
            isFirst.value = false
            isEnd.value = false
          } else if (clientOffset.y - hoverBoundingRect.top < 24 && clientOffset.y - hoverBoundingRect.top > 5 && findVisibleLength(layout.value.bottom[props.index].children) > 1 && item.pid === props.info.id) {
            position.value = 'self'
            isNear.value = true
            isNearSelf.value = true
            dropTo.value = props.info.config.position
            dropIndex.value = -1
            dropId.value = props.info.id
            dropLevel.value = 'item'
            isFirst.value = false
            isEnd.value = false
          } else if (clientOffset.y - hoverBoundingRect.top < 24 && clientOffset.y - hoverBoundingRect.top > 5 && item.pid !== props.info.id) {
            position.value = 'self'
            isNear.value = true
            isNearSelf.value = false
            dropTo.value = props.info.config.position
            dropIndex.value = -1
            dropId.value = props.info.id
            dropLevel.value = 'item'
            isFirst.value = false
            isEnd.value = false
          } else if (clientOffset.y - hoverBoundingRect.top <= 5 && props.index !== 0 && (item.pid !== props.info.id || item.pid === props.info.id && findVisibleLength(layout.value.bottom[dragTabIndex].children) > 1) && (nearTabBeforeIndex < 0 || (nearTabBeforeIndex > 0 && props.index !== nearTabBeforeIndex))) {
            position.value = 'top'
            isNear.value = true
            isNearSelf.value = false
            dropTo.value = props.info.config.position
            dropIndex.value = getNearDropIndex(nearTabBeforeIndex, props.index, 'before')
            dropId.value = ''
            dropLevel.value = 'tab'
            isFirst.value = false
            isEnd.value = false
          } else if (hoverBoundingRect.bottom - clientOffset.y <= 5 && (item.pid !== props.info.id || item.pid === props.info.id && findVisibleLength(layout.value.bottom[dragTabIndex].children) > 1) && (nearTabAfterIndex < 0 || (nearTabAfterIndex >= 0 && props.index !== nearTabAfterIndex))) {
            position.value = 'bottom'
            isNear.value = true
            isNearSelf.value = false
            dropTo.value = props.info.config.position
            dropIndex.value = getNearDropIndex(nearTabAfterIndex, props.index, 'after')
            dropId.value = ''
            dropLevel.value = 'tab'
            isFirst.value = false
            isEnd.value = props.index === findLastVisible(layout.value.bottom)
          } else {
            position.value = ''
            isNear.value = false
            isNearSelf.value = false
            dropTo.value = 'root'
            dropIndex.value = -1
            dropId.value = ''
            dropLevel.value = 'aside'
            isFirst.value = false
            isEnd.value = false
          }
        } else {
          // 放置的是root中的tab
          const dragAsideIndex = item.config.position === 'root' ? layout.value.root.findIndex((v) => v.id === item.parent[item.parent.length - 1]) : -1
          const dropParent = getParent(layout.value.root, props.info.id)
          const dropAsideIndex = layout.value.root.findIndex((v) => v.id === dropParent[dropParent.length - 1])
          // 拖拽对象所在列的索引
          const dragColumnIndex = dragAsideIndex === -1 ? -1 : layout.value.root[dragAsideIndex].children.findIndex((v) => v.id === item.parent[item.parent.length - 2])
          const dragTabIndex = item.config.position !== 'root' || dragColumnIndex < 0 || dragAsideIndex < 0 ? -1 : layout.value.root[dragAsideIndex].children[dragColumnIndex].children.findIndex((v) => v.id === item.parent[item.parent.length - 3])
          // 当前放置对象所在列的索引
          const dropColumnIndex = layout.value.root[dropAsideIndex].children.findIndex((v) => v.id === dropParent[dropParent.length - 2])
          // 查找当当前拖拽项所在列数组长度为1时，其临近列的索引，该种情况下，当前拖拽项不可被放置在临近列（也就是不可放在自己本身的位置）
          const nearColumnBeforeIndex = item.parent[item.parent.length - 1] === dropParent[dropParent.length - 1] && findVisibleLength(layout.value[item.config.position][dragAsideIndex].children[dragColumnIndex].children) === 1 && findVisibleLength(layout.value[item.config.position][dragAsideIndex].children[dragColumnIndex].children[dragTabIndex].children) === 1 ? getNearIndex(layout.value[item.config.position][dragAsideIndex].children, dragColumnIndex, 'before') : -1
          const nearColumnAfterIndex = item.parent[item.parent.length - 1] === dropParent[dropParent.length - 1] && findVisibleLength(layout.value[item.config.position][dragAsideIndex].children[dragColumnIndex].children) === 1 && findVisibleLength(layout.value[item.config.position][dragAsideIndex].children[dragColumnIndex].children[dragTabIndex].children) === 1 ? getNearIndex(layout.value[item.config.position][dragAsideIndex].children, dragColumnIndex, 'after') : -1
          const nearTabBeforeIndex = item.parent[item.parent.length - 2] === dropParent[dropParent.length - 2] && findVisibleLength(layout.value[item.config.position][dragAsideIndex].children[dragColumnIndex].children) > 1 && findVisibleLength(layout.value[item.config.position][dragAsideIndex].children[dragColumnIndex].children[dragTabIndex].children) === 1 ? getNearIndex(layout.value[item.config.position][dragAsideIndex].children[dragColumnIndex].children, dragTabIndex, 'before') : -1
          const nearTabAfterIndex = item.parent[item.parent.length - 2] === dropParent[dropParent.length - 2] && findVisibleLength(layout.value[item.config.position][dragAsideIndex].children[dragColumnIndex].children) > 1 && findVisibleLength(layout.value[item.config.position][dragAsideIndex].children[dragColumnIndex].children[dragTabIndex].children) === 1 ? getNearIndex(layout.value[item.config.position][dragAsideIndex].children[dragColumnIndex].children, dragTabIndex, 'after') : -1
          const isAloneTabSelf = isAloneSelf(layout.value.root[dropAsideIndex].children[dropColumnIndex], item)
          if (clientOffset.x - hoverBoundingRect.left < 10 && !isAloneTabSelf && (nearColumnBeforeIndex < 0 || (nearColumnBeforeIndex > 0 && dropColumnIndex !== nearColumnBeforeIndex))) {
            position.value = 'left'
            isNear.value = true
            isNearSelf.value = false
            dropTo.value = 'root'
            dropIndex.value = getNearDropIndex(nearColumnBeforeIndex, dropColumnIndex, 'before')
            dropId.value = layout.value.root[dropAsideIndex].id
            dropLevel.value = 'column'
            isFirst.value = dropColumnIndex === findFirstVisible(layout.value[props.info.config.position][dropAsideIndex].children)
            isEnd.value = false
          } else if (hoverBoundingRect.right - clientOffset.x < 10 && !isAloneTabSelf && (nearColumnAfterIndex < 0 || (nearColumnAfterIndex >= 0 && dropColumnIndex !== nearColumnAfterIndex))) {
            position.value = 'right'
            isNear.value = true
            isNearSelf.value = false
            dropTo.value = 'root'
            dropIndex.value = getNearDropIndex(nearColumnAfterIndex, dropColumnIndex, 'after')
            dropId.value = layout.value.root[dropAsideIndex].id
            dropLevel.value = 'column'
            isFirst.value = false
            isEnd.value = dropColumnIndex === findLastVisible(layout.value[props.info.config.position][dropAsideIndex].children)
          } else if (clientOffset.y - hoverBoundingRect.top < 24 && clientOffset.y - hoverBoundingRect.top > 5 && item.pid === props.info.id && !(findVisibleLength(layout.value.root[dragAsideIndex].children) === 1 && findVisibleLength(layout.value.root[dragAsideIndex].children[findFirstVisible(layout.value[props.info.config.position][dropAsideIndex].children)].children) === 1 && findVisibleLength(layout.value.root[dragAsideIndex].children[findFirstVisible(layout.value[props.info.config.position][dropAsideIndex].children)].children[findFirstVisible(layout.value.root[dragAsideIndex].children[findFirstVisible(layout.value[props.info.config.position][dropAsideIndex].children)].children)].children) === 1)) {
            position.value = 'self'
            isNear.value = true
            isNearSelf.value = true
            dropTo.value = props.info.config.position
            dropIndex.value = getDropIndex(layout.value, dropAsideIndex, dropColumnIndex, props.info, props.index, item.config.dragType)
            dropId.value = getDropId(layout.value, dropAsideIndex, dropColumnIndex, props.info, props.index, item.config.dragType)
            dropLevel.value = getDropLevel(layout.value, dropAsideIndex, dropColumnIndex, props.info, props.index, item.config.dragType)
            isFirst.value = false
            isEnd.value = false
          } else if (clientOffset.y - hoverBoundingRect.top < 24 && clientOffset.y - hoverBoundingRect.top > 5 && item.pid !== props.info.id) {
            position.value = 'self'
            isNear.value = true
            isNearSelf.value = false
            dropTo.value = props.info.config.position
            dropIndex.value = -1
            dropId.value = props.info.id
            dropLevel.value = 'item'
            isFirst.value = false
            isEnd.value = false
          } else if (clientOffset.y - hoverBoundingRect.top <= 5 && (item.pid !== props.info.id || item.pid === props.info.id && findVisibleLength(layout.value.root[dropAsideIndex].children[dropColumnIndex].children[dragTabIndex].children) > 1) && (nearTabBeforeIndex < 0 || (nearTabBeforeIndex > 0 && props.index !== nearTabBeforeIndex))) {
            position.value = 'top'
            isNear.value = true
            isNearSelf.value = false
            dropTo.value = props.info.config.position
            dropIndex.value = getNearDropIndex(nearTabBeforeIndex, props.index, 'before')
            dropId.value = props.info.pid
            dropLevel.value = 'tab'
            isFirst.value = props.index === findFirstVisible(layout.value[props.info.config.position][dropAsideIndex].children[dropColumnIndex].children)
            isEnd.value = false
          } else if (hoverBoundingRect.bottom - clientOffset.y <= 5 && (item.pid !== props.info.id || item.pid === props.info.id && findVisibleLength(layout.value.root[dropAsideIndex].children[dropColumnIndex].children[dragTabIndex].children) > 1) && (nearTabAfterIndex < 0 || (nearTabAfterIndex >= 0 && props.index !== nearTabAfterIndex))) {
            position.value = 'bottom'
            isNear.value = true
            isNearSelf.value = false
            dropTo.value = props.info.config.position
            dropIndex.value = getNearDropIndex(nearTabAfterIndex, props.index, 'after')
            dropId.value = props.info.pid
            dropLevel.value = 'tab'
            isFirst.value = false
            isEnd.value = props.index === findLastVisible(layout.value[props.info.config.position][dropAsideIndex].children[dropColumnIndex].children)
          } else {
            position.value = ''
            isNear.value = false
            isNearSelf.value = false
            dropTo.value = 'root'
            dropIndex.value = -1
            dropId.value = ''
            dropLevel.value = 'aside'
            isFirst.value = false
            isEnd.value = false
          }
        }
      }
    } else {
      // 拖拽的aside
      if (props.info.config.position === 'left' || props.info.config.position === 'right') {
        // 当前放置对象所在列的索引
        const dropColumnIndex = layout.value[props.info.config.position][0].children.findIndex((v) => v.id === props.info.pid)
        if (clientOffset.x - hoverBoundingRect.left < 10 && props.info.config.position === 'left' && item.config.position !== props.info.config.position) {
          position.value = 'left'
          isNear.value = true
          isNearSelf.value = false
          dropTo.value = 'left'
          dropIndex.value = dropColumnIndex
          dropId.value = layout.value.left[0].id
          dropLevel.value = 'column'
          isFirst.value = dropColumnIndex === findFirstVisible(layout.value[props.info.config.position][0].children)
          isEnd.value = false
        } else if (hoverBoundingRect.right - clientOffset.x < 10 && props.info.config.position === 'left' && item.config.position !== props.info.config.position && dropColumnIndex !== findLastVisible(layout.value[props.info.config.position][0].children)) {
          position.value = 'right'
          isNear.value = true
          isNearSelf.value = false
          dropTo.value = 'left'
          dropIndex.value = dropColumnIndex + 1
          dropId.value = layout.value.left[0].id
          dropLevel.value = 'column'
          isFirst.value = false
          isEnd.value = false
        } else if (clientOffset.x - hoverBoundingRect.left < 10 && props.info.config.position === 'right' && item.config.position !== props.info.config.position && dropColumnIndex !== findFirstVisible(layout.value[props.info.config.position][0].children)) {
          position.value = 'left'
          isNear.value = true
          isNearSelf.value = false
          dropTo.value = 'right'
          dropIndex.value = dropColumnIndex
          dropId.value = layout.value.right[0].id
          dropLevel.value = 'column'
          isFirst.value = false
          isEnd.value = false
        } else if (hoverBoundingRect.right - clientOffset.x < 10 && props.info.config.position === 'right' && item.config.position !== props.info.config.position) {
          position.value = 'right'
          isNear.value = true
          isNearSelf.value = false
          dropTo.value = 'right'
          dropIndex.value = dropColumnIndex + 1
          dropId.value = layout.value.right[0].id
          dropLevel.value = 'column'
          isFirst.value = false
          isEnd.value = dropColumnIndex === findLastVisible(layout.value[props.info.config.position][0].children)
        } else if (clientOffset.y - hoverBoundingRect.top < 24 && clientOffset.y - hoverBoundingRect.top > 5 && findVisibleLength(item.children) === 1 && findVisibleLength(item.children[findFirstVisible(item.children)].children) === 1 && item.children[findFirstVisible(item.children)].children[findFirstVisible(item.children[findFirstVisible(item.children)].children)].config.dragType === 'tab') {
          position.value = 'self'
          isNear.value = true
          isNearSelf.value = false
          dropTo.value = props.info.config.position
          dropIndex.value = -1
          dropId.value = props.info.id
          dropLevel.value = 'item'
          isFirst.value = false
          isEnd.value = false
        } else if (clientOffset.y - hoverBoundingRect.top <= 5 && findVisibleLength(item.children) === 1 && (findVisibleLength(item.children[findFirstVisible(item.children)].children) === 1 && item.children[findFirstVisible(item.children)].children[findFirstVisible(item.children[findFirstVisible(item.children)].children)].config.dragType === 'tab' || findVisibleLength(item.children[findFirstVisible(item.children)].children) > 1)) {
          position.value = 'top'
          isNear.value = true
          isNearSelf.value = false
          dropTo.value = props.info.config.position
          dropIndex.value = props.index
          dropId.value = props.info.pid
          dropLevel.value = 'tab'
          isFirst.value = props.index === findFirstVisible(layout.value[props.info.config.position][0].children[dropColumnIndex].children)
          isEnd.value = false
        } else if (hoverBoundingRect.bottom - clientOffset.y <= 5 && findVisibleLength(item.children) === 1 && (findVisibleLength(item.children[findFirstVisible(item.children)].children) === 1 && item.children[findFirstVisible(item.children)].children[findFirstVisible(item.children[findFirstVisible(item.children)].children)].config.dragType === 'tab' || findVisibleLength(item.children[findFirstVisible(item.children)].children) > 1)) {
          position.value = 'bottom'
          isNear.value = true
          isNearSelf.value = false
          dropTo.value = props.info.config.position
          dropIndex.value = props.index + 1
          dropId.value = props.info.pid
          dropLevel.value = 'tab'
          isFirst.value = false
          isEnd.value = props.index === findLastVisible(layout.value[props.info.config.position][0].children[dropColumnIndex].children)
        } else {
          position.value = ''
          isNear.value = false
          isNearSelf.value = false
          dropTo.value = 'root'
          dropIndex.value = -1
          dropId.value = ''
          dropLevel.value = 'aside'
          isFirst.value = false
          isEnd.value = false
        }
      } else if (props.info.config.position === 'bottom') {
        if (clientOffset.y - hoverBoundingRect.top < 24 && clientOffset.y - hoverBoundingRect.top > 5 && findVisibleLength(item.children) === 1 && findVisibleLength(item.children[findFirstVisible(item.children)].children) === 1 && item.children[findFirstVisible(item.children)].children[findFirstVisible(item.children[findFirstVisible(item.children)].children)].config.dragType === 'tab') {
          position.value = 'self'
          isNear.value = true
          isNearSelf.value = false
          dropTo.value = props.info.config.position
          dropIndex.value = -1
          dropId.value = props.info.id
          dropLevel.value = 'item'
          isFirst.value = false
          isEnd.value = false
        } else if (clientOffset.y - hoverBoundingRect.top <= 5 && props.index !== findFirstVisible(layout.value.bottom) && findVisibleLength(item.children) === 1 && (findVisibleLength(item.children[findFirstVisible(item.children)].children) === 1 && item.children[findFirstVisible(item.children)].children[findFirstVisible(item.children[findFirstVisible(item.children)].children)].config.dragType === 'tab' || findVisibleLength(item.children[findFirstVisible(item.children)].children) > 1)) {
          position.value = 'top'
          isNear.value = true
          isNearSelf.value = false
          dropTo.value = props.info.config.position
          dropIndex.value = props.index
          dropId.value = ''
          dropLevel.value = 'tab'
          isFirst.value = false
          isEnd.value = false
        } else if (hoverBoundingRect.bottom - clientOffset.y <= 5 && findVisibleLength(item.children) === 1 && (findVisibleLength(item.children[findFirstVisible(item.children)].children) === 1 && item.children[findFirstVisible(item.children)].children[findFirstVisible(item.children[findFirstVisible(item.children)].children)].config.dragType === 'tab' || findVisibleLength(item.children[findFirstVisible(item.children)].children) > 1)) {
          position.value = 'bottom'
          isNear.value = true
          isNearSelf.value = false
          dropTo.value = props.info.config.position
          dropIndex.value = props.index + 1
          dropId.value = ''
          dropLevel.value = 'tab'
          isFirst.value = false
          isEnd.value = props.index === findLastVisible(layout.value.bottom)
        } else {
          position.value = ''
          isNear.value = false
          isNearSelf.value = false
          dropTo.value = 'root'
          dropIndex.value = -1
          dropId.value = ''
          dropLevel.value = 'aside'
          isFirst.value = false
          isEnd.value = false
        }
      } else if (props.info.config.position === 'root') {
        // 放置的是root中的tab
        const dropParent = getParent(layout.value.root, props.info.id)
        const dropAsideIndex = layout.value.root.findIndex((v) => v.id === dropParent[dropParent.length - 1])
        // 当前放置对象所在列的索引
        const dropColumnIndex = layout.value.root[dropAsideIndex].children.findIndex((v) => v.id === dropParent[dropParent.length - 2])
        if (clientOffset.x - hoverBoundingRect.left < 10 && item.id !== layout.value.root[dropAsideIndex].id) {
          position.value = 'left'
          isNear.value = true
          isNearSelf.value = false
          dropTo.value = 'root'
          dropIndex.value = dropColumnIndex
          dropId.value = layout.value.root[dropAsideIndex].id
          dropLevel.value = 'column'
          isFirst.value = dropColumnIndex === findFirstVisible(layout.value[props.info.config.position][dropAsideIndex].children)
          isEnd.value = false
        } else if (hoverBoundingRect.right - clientOffset.x < 10 && item.id !== layout.value.root[dropAsideIndex].id) {
          position.value = 'right'
          isNear.value = true
          isNearSelf.value = false
          dropTo.value = 'root'
          dropIndex.value = dropColumnIndex + 1
          dropId.value = layout.value.root[dropAsideIndex].id
          dropLevel.value = 'column'
          isFirst.value = false
          isEnd.value = dropColumnIndex === findLastVisible(layout.value[props.info.config.position][dropAsideIndex].children)
        } else if (clientOffset.y - hoverBoundingRect.top < 24 && clientOffset.y - hoverBoundingRect.top > 5 && findVisibleLength(item.children) === 1 && findVisibleLength(item.children[findFirstVisible(item.children)].children) === 1 && item.children[findFirstVisible(item.children)].children[findFirstVisible(item.children[findFirstVisible(item.children)].children)].config.dragType === 'tab' && item.id !== dropParent[dropParent.length - 1]) {
          position.value = 'self'
          isNear.value = true
          isNearSelf.value = false
          dropTo.value = props.info.config.position
          dropIndex.value = -1
          dropId.value = props.info.id
          dropLevel.value = 'item'
          isFirst.value = false
          isEnd.value = false
        } else if (clientOffset.y - hoverBoundingRect.top <= 5 && findVisibleLength(item.children) === 1 && (findVisibleLength(item.children[findFirstVisible(item.children)].children) === 1 && item.children[findFirstVisible(item.children)].children[findFirstVisible(item.children[findFirstVisible(item.children)].children)].config.dragType === 'tab' || findVisibleLength(item.children[findFirstVisible(item.children)].children) > 1) && item.id !== dropParent[dropParent.length - 1]) {
          position.value = 'top'
          isNear.value = true
          isNearSelf.value = false
          dropTo.value = props.info.config.position
          dropIndex.value = props.index
          dropId.value = props.info.pid
          dropLevel.value = 'tab'
          isFirst.value = props.index === findFirstVisible(layout.value[props.info.config.position][0].children[dropColumnIndex].children)
          isEnd.value = false
        } else if (hoverBoundingRect.bottom - clientOffset.y <= 5 && findVisibleLength(item.children) === 1 && (findVisibleLength(item.children[findFirstVisible(item.children)].children) === 1 && item.children[findFirstVisible(item.children)].children[findFirstVisible(item.children[findFirstVisible(item.children)].children)].config.dragType === 'tab' || findVisibleLength(item.children[findFirstVisible(item.children)].children) > 1) && item.id !== dropParent[dropParent.length - 1]) {
          position.value = 'bottom'
          isNear.value = true
          isNearSelf.value = false
          dropTo.value = props.info.config.position
          dropIndex.value = props.index + 1
          dropId.value = props.info.pid
          dropLevel.value = 'tab'
          isFirst.value = false
          isEnd.value = props.index === findLastVisible(layout.value[props.info.config.position][0].children[dropColumnIndex].children)
        } else {
          position.value = ''
          isNear.value = false
          isNearSelf.value = false
          dropTo.value = 'root'
          dropIndex.value = -1
          dropId.value = ''
          dropLevel.value = 'aside'
          isFirst.value = false
          isEnd.value = false
        }
      } else {
        position.value = ''
        isNear.value = false
        isNearSelf.value = false
        dropTo.value = 'root'
        dropIndex.value = -1
        dropId.value = ''
        dropLevel.value = 'aside'
        isFirst.value = false
        isEnd.value = false
      }
    }
  },
  collect(monitor) {
    return {
      isOver: monitor.isOver(),
      isOverCurrent: monitor.isOver({ shallow: true })
    }
  },
  drop(item) {
    if (dropTo.value === 'left' || dropTo.value === 'right' || dropTo.value === 'bottom') {
      const res: any = cloneDeep(item)
      res.options.attr.x = 0
      res.options.attr.y = 0
      layoutStore.moveLayout(res)
    }
  }
})
const { isOver, isOverCurrent } = toRefs(dropCollect)

const [dragCollect, drag, preview] = useDrag({
  type: props.info.config.dragType,
  item: () => {
    const res = cloneDeep(props.info)
    res.component = null
    res.index = props.index
    if (res.config.position === 'left') {
      res.parent = getParent(layout.value.left, res.id)
      const index = layout.value.left[0].children.findIndex((v) => v.id === res.parent[res.parent.length - 2])
      if (index === findLastVisible(layout.value.left[0].children) && findVisibleLength(layout.value.left[0].children[index].children) === 1) {
        res.isNearMain = true
      } else {
        res.isNearMain = false
      }
    } else if (res.config.position === 'right') {
      res.parent = getParent(layout.value.right, res.id)
      const index = layout.value.right[0].children.findIndex((v) => v.id === res.parent[res.parent.length - 2])
      if (index === findFirstVisible(layout.value.right[0].children) && findVisibleLength(layout.value.right[0].children[index].children) === 1) {
        res.isNearMain = true
      } else {
        res.isNearMain = false
      }
    } else if (res.config.position === 'bottom') {
      res.parent = getParent(layout.value.bottom, res.id)
      const index = layout.value.bottom.findIndex((v) => v.id === res.id)
      if (index === findFirstVisible(layout.value.bottom) && findVisibleLength(layout.value.bottom) === 1) {
        res.isNearMain = true
      } else {
        res.isNearMain = false
      }
    } else {
      res.parent = getParent(layout.value.root, res.id)
      res.isNearMain = false
    }
    layoutStore.setCurrentDraggingPreviewModule(res)
    return res
  },
  canDrag: () => {
    return props.info.config.canDrag
  },
  collect: (monitor) => ({
    isDragging: monitor.isDragging()
  })
})

const { isDragging } = toRefs(dragCollect)

const setRef = (el) => {
  cardRef.value = drop(el)
}

watch(
  () => isDragging.value,
  (value) => {
    isLayoutDragging.value = value
  }
)

const setTrigger = () => {
  if (props.info.config.position === 'left') {
    return 'right-start'
  } else if (props.info.config.position === 'right') {
    return 'left-start'
  } else if (props.info.config.position === 'bottom') {
    return 'top'
  } else {
    return 'bottom'
  }
}

const setClass = computed(() => {
  return {
    active: isNearSelf.value && isOverCurrent.value || isNearSelf.value && currentDragModule.value && currentDragModule.value.config.dragType === 'item',
    'item-active': currentDragModule.value && currentDragModule.value.config.dragType === 'item' && currentDragModule.value.pid === props.info.id && !isItemSort.value && isNearSelf.value,
    near: isLayoutDragging.value && isOverCurrent.value && position.value === 'self' && !isNearSelf.value || currentDragModule.value && currentDragModule.value.config.dragType === 'item' && !isItemSort.value && currentDragModule.value.pid !== props.info.id && position.value === 'self' && !isNearSelf.value && isNear.value && isOver.value,
    'is-dragging': isDragging.value || currentDragModule.value && currentDragModule.value.config.dragType === 'item' && currentDragModule.value.pid === props.info.id && findVisibleLength(props.info.children) === 1,
    'is-drag': currentDragModule.value && currentDragModule.value.config.dragType === 'item' && currentDragModule.value.pid === props.info.id && currentDragModule.value.active,
    preview: props.preview,
    default: !props.preview,
    'left': props.info.config.position === 'left',
    'right': props.info.config.position === 'right',
    'root': props.info.config.position === 'root'
  }
})

const setStyle = () => {
  if (props.preview) {
    return {
      width: props.info.options.attr.w + 'px'
    }
  } else {
    return ''
  }
}

onMounted(() => {
  preview(getEmptyImage(), { captureDraggingState: true })
})
</script>

<template>
  <div :ref="setRef" class="tabs-pane" :class="props.preview ? 'preview' : ''">
    <div class="el-tabs el-tabs--top el-tabs--border-card" :class="setClass" :style="setStyle()">
      <div class="el-tabs__header is-top">
        <div v-if="!props.preview" :ref="drag" class="drag-handle"></div>
        <div class="tabs-header"></div>
        <el-popover :width="120" trigger="click" :placement="setTrigger()" :show-arrow="false" :offset="10" :popper-style="{ padding: 0 }" popper-class="big-screen">
          <template #reference>
            <div class="tab-icon">
              <SvgIcon icon="ri:menu-line"></SvgIcon>
            </div>
          </template>
          <div class="tab-operation">
            <div class="item-operation">关闭</div>
            <div class="item-operation">关闭选项卡组</div>
            <div class="item-operation">最小化</div>
            <div class="item-operation">折叠为图标</div>
          </div>
        </el-popover>
        <div class="el-tabs__nav-wrap is-top">
          <div class="el-tabs__nav-scroll">
            <div class="el-tabs__nav is-top">
              <template v-if="props.info.children && props.info.children.length > 0">
                <template v-for="item, index in props.info.children" :key="index">
                  <CkItem v-if="item.visible" :info="item" :preview="props.preview" :index="index"></CkItem>
                </template>
              </template>
            </div>
          </div>
        </div>
      </div>
      <div class="el-tabs__content">
        <template v-if="props.info.children && props.info.children.length > 0">
          <template v-for="item, index in props.info.children" :key="index">
            <div v-if="item.visible" class="el-tab-pane" :class="item.active ? 'is-active' : ''" :style="{ display: item.active ? '' : 'none' }">
              <component :is="item.component"></component>
            </div>
          </template>
        </template>
      </div>
      <div v-if="isLayoutDragging && isOverCurrent && (position === 'top' || position === 'bottom')" :class="['indicator', position, isEnd ? 'is-end' : '', isFirst ? 'is-first' : '']"></div>
    </div>
    <div v-if="isLayoutDragging && isOverCurrent && (position === 'left' || position === 'right')" :class="['indicator', props.info.config.position === 'root' ? 'root' : '', position, isEnd ? 'is-end' : '', isFirst ? 'is-first' : '']"></div>
  </div>
</template>

<style scoped lang="scss">
.tabs-pane {
  display: flex;
  flex: 1;
  width: 100%;
  pointer-events: auto;

  &.preview {
    transition: opacity 0.3s;
    pointer-events: none;

    * {
      pointer-events: none;
    }

    .el-tabs__item {
      background-color: var(--el-bg-color-overlay) !important;

      &.is-active {
        color: var(--el-text-color-regular) !important;
        background-color: var(--el-header-bg-color) !important;

        :deep(.tab-item-label) {
          &::after {
            background-color: transparent !important;
          }
        }
      }
    }
  }
}

.el-tabs__nav-scroll {
  pointer-events: none;
}

.el-tabs__nav {
  flex-wrap: nowrap;
  white-space: inherit;
  pointer-events: auto;
}

.el-tabs {
  --el-tabs-header-height: 28px;

  position: relative;
  display: flex;
  flex: 1;
  flex-direction: column;
  width: 100%;

  .el-tabs__content {
    flex: 1;
  }

  &.default {
    &.near {
      &::before {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        border: 2px solid var(--el-color-primary);
        content: '';
      }

      .el-tabs__header {
        position: relative;

        .tabs-header {
          position: absolute;
          top: 0;
          left: 0;
          z-index: 10;
          width: 100%;
          height: 28px;
          border: 2px solid var(--el-color-primary);
          border-bottom: none;
        }

        .drag-handle {
          background-color: var(--el-color-primary-light-7);
        }

        .el-tabs__nav {
          pointer-events: none;
        }
      }
    }
  }

  &.is-dragging {
    * {
      opacity: 0;
    }

    &.active {
      &::before {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        border: 2px solid var(--el-color-primary);
        content: '';
      }
    }
  }

  &.is-drag {
    .el-tabs__content {
      .is-active {
        opacity: 0;
      }
    }
  }

  &.item-active {

    .el-tabs__header {
      &::before {
        position: absolute;
        bottom: -1px;
        left: 0;
        width: 100%;
        height: 2px;
        background-color: var(--el-color-primary);
        content: '';
      }

      .el-tabs__item {
        z-index: 1;

        :deep(.tab-item-label) {
          &::after {
            height: 2px;
            background-color: var(--el-color-primary);
          }
        }

        &.is-check {
          z-index: 2;
          padding: 0 !important;
          color: var(--el-text-color-disabled) !important;
          background-color: var(--el-bg-color-overlay) !important;

          &:first-child {
            &::before {
              left: 1px;
            }
          }

          &::before,
          &::after {
            width: 2px;
            background-color: var(--el-color-primary);
          }

          :deep(.tab-item-label) {
            &::before {
              top: 1px;
              height: 2px;
              background-color: var(--el-color-primary);
            }

            &::after {
              background-color: transparent;
            }
          }

          &.is-active {
            color: var(--el-text-color-regular) !important;
            background-color: var(--el-header-bg-color) !important;

            :deep(.tab-item-label) {
              &::after {
                height: 2px;
                background-color: transparent !important;
              }
            }
          }
        }

        &.is-active {

          :deep(.tab-item-label) {
            &::after {
              height: 2px;
              background-color: var(--el-color-primary);
            }
          }
        }
      }
    }

    .el-tabs__content {
      &::before {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        border: 2px solid var(--el-color-primary);
        border-top: none;
        content: '';
      }
    }
  }
}

.el-tabs--border-card {
  background-color: var(--el-header-bg-color);
  border: 1px solid var(--el-bg-color-page);

  &.preview {
    >.el-tabs__header {

      .el-tabs__nav {
        pointer-events: none;
      }
    }
  }

  >.el-tabs__header {
    padding-right: 40px;
    background-color: var(--el-bg-color-overlay);
    border-bottom: 1px solid var(--el-bg-color-page);

    .drag-handle {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
    }

    .tab-icon {
      position: absolute;
      top: 5px;
      right: 5px;
      z-index: 3;
      display: flex;
      align-items: center;
      justify-content: center;
      width: 16px;
      height: 16px;
      border: 1px solid transparent;
      border-radius: 2px;

      &:hover {
        border-color: var(--el-fill-color-darker);
      }

      .el-icon {
        font-size: 12px !important;
      }
    }

    .el-tabs__nav-wrap {
      z-index: 1;
      pointer-events: none;
    }
  }
}

.indicator {
  position: absolute;
  z-index: 10;

  &.top {
    top: -4px;
    right: 0;
    left: 0;
    height: 0;
    border-top: 5px solid var(--el-color-primary);

    &.is-first {
      top: 0;
    }
  }

  &.right {
    top: 0;
    right: -3px;
    bottom: 0;
    width: 0;
    border-left: 5px solid var(--el-color-primary);

    &.is-end {
      right: 0;
    }
  }

  &.bottom {
    right: 0;
    bottom: -4px;
    left: 0;
    height: 0;
    border-top: 5px solid var(--el-color-primary);

    &.is-end {
      bottom: 0;
    }
  }

  &.left {
    top: 0;
    bottom: 0;
    left: -3px;
    width: 0;
    border-left: 5px solid var(--el-color-primary);

    &.root {
      left: -2px;
    }

    &.is-first {
      left: 0;
    }
  }
}
</style>
<style lang="scss">
.big-screen{
  * {
    -webkit-touch-callout: none;
    user-select: none;
  }

  input {
    user-select: auto;
  }

  textarea {
    user-select: auto;
  }
}

.tab-operation {
  padding: 4px;

  .item-operation {
    height: 26px;
    padding: 0 10px;
    line-height: 26px;
  }
}
</style>
